import { computed, reactive,defineComponent, onBeforeMount, onMounted, Ref, ref, SetupContext, watch, onUnmounted } from 'vue';
import { MemoryVoiceCarouselProps, memoryVoiceCarouselProps } from './carousel.props';
import './carousel.scss';

export default defineComponent({
    name: 'FMemoryVoiceCarousel',
    props: memoryVoiceCarouselProps,
    emits: ['change'],
    setup(props: MemoryVoiceCarouselProps, context: SetupContext) {
        let timer: any = null;
        let keyx: boolean = true; // 防抖
        const state = reactive({
            asyncIndex: 0, // 异步索引
            nowIndex: 0, // 当前实时索引（同步）
            animationLock: true, // 是否为第一次加载
            direction: 'left', // 控制切换方向 left向左，right向右
            isReady: true, // 用于外部停止轮播锁止
            isMoveSlot: true, // 插槽1是否为【移出插槽】 两个插槽轮流当做【移出插槽】，true插槽1为【移出插槽】；false插槽2为【移出插槽】
            slot1Show: true, // 插槽1是否显示
            slot2Show: false // 插槽2是否显示
        });
        const width = ref(props.width);
        const animationType = ref(props.animationType);
        const height = ref(props.height);
        const animationTime = ref(props.animationTime);
        const groupType = ref(props.groupType);
        const defaultDir = ref(props.defaultDir);

        // 获取下一页索引
        const nextIndex = (): number => {
            if (state['asyncIndex'] === props.list.length - 1) return 0;
            return state['asyncIndex'] + 1;
        };

        // 获取上一页索引
        const prevIndex = (): number => {
            if (state['asyncIndex'] === 0) return props.list.length - 1;
            return state['asyncIndex'] - 1;
        };

        /**
         * 处理方向
         * @param index 索引
         * @param from 来源 bom 直接操作索引 other：左右切换按钮/自动轮播
         * @param direction 轮播方向
         */

        const handleDirection = (index: number, from: string, direction?: string) => {
            // 如果来源是next则直接改变direction
            // 如果来源是bom则计算direction
            if (from === 'bom') {
                if (index > state['asyncIndex']) state['direction'] = 'left';
                else if (index < state['syncIndex']) state['direction'] = 'right';
                else state['direction'] = 'left';
            } else if (from === 'next') {
                state['direction'] = direction||'';
            }
        };

        // 处理切换【移出插槽】逻辑
        const handleSwitchSlot = (index: number) => {
            // 插槽1是【移出插槽】
            if (state['isMoveSlot']) {
                state['slot1Show'] = false; // 先隐藏掉插槽1
                state['animationLock'] = true; // 打开动画锁
                state['isMoveSlot'] = false; // 更改【移出插槽】 false：插槽2为【移出插槽】
            } else {
                // 插槽2是【移出插槽】
                state['slot2Show'] = false;
                state['animationLock'] = true;
                state['isMoveSlot'] = true;
            }

            // 更新索引
            state['asyncIndex'] = index;

            // 一轮防抖结束
            keyx = true;
        };

        /**
         * 跳转页
         * @param index 索引
         * @param from 来源 bom 直接操作索引 other：左右切换按钮/自动轮播
         * @param direction 轮播方向
         */

        const goCurrent = (index: number, from: string, direction?: string) => {
            // 禁止条件
            if (!state['isReady']) return; // 外部锁止
            if (state['asyncIndex'] === index) return; // 禁止点击同一索引

            // 防抖
            if (!keyx) return;
            keyx = false;

            // 处理轮播方向
            handleDirection(index, from, direction);

            // 更新当前（实时索引）
            state['nowIndex'] = index;
            context.emit('changeIndex', index);

            // 打开动画锁
            state['animationLock'] = false;

            // 判断当前谁是【移出插槽】
            // 插槽1是【移出插槽】
            if (state['isMoveSlot']) state['slot2Show'] = true;
            // 插槽2是【移出插槽】
            else state['slot1Show'] = true;

            // 移动结束
            setTimeout(() => {
                setTimeout(() => {
                    handleSwitchSlot(index);
                }, props.animationTime * 1000 - 50);
            }, 10);
        };

        // 开始滚动
        const startGroup = () => {
            stopGroup();
            timer = setInterval(() => {
                // 正向/反向 默认方向
                if (defaultDir.value === 'reverse') goCurrent(prevIndex(), 'next', 'right');
                else goCurrent(nextIndex(), 'next', 'left');
            }, props.speed);
        };

        // 停止滚动
        const stopGroup = () => {
            if (timer) {
                clearInterval(timer);
                timer = null;
            }
        };

        // 两侧切换
        const changeCurrent = (type: string) => {
            if (!type || typeof type !== 'string') return;
            if (type === 'prev') {
                if (defaultDir.value === 'reverse') goCurrent(nextIndex(), 'next', 'left');
                else goCurrent(prevIndex(), 'next', 'right');
            } else if (type === 'next') {
                if (defaultDir.value === 'reverse') goCurrent(prevIndex(), 'next', 'right');
                else goCurrent(nextIndex(), 'next', 'left');
            } else return;
        };

        const getSlotIndex = (slot: string) => {
            if (slot === 'slot1') {
                // 插槽1 且插槽1为【移出插槽】 则返回 旧索引
                if (!state['isMoveSlot']) return state['nowIndex'];
                // 新索引
                else return state['asyncIndex'];
            } else {
                // 插槽2 且插槽2为【移出插槽】 则返回 旧索引
                if (state['isMoveSlot']) return state['nowIndex'];
                // 新索引
                else return state['asyncIndex'];
            }
        };

        onMounted(() => {
            startGroup();
        });

        onUnmounted(() => {
            if (timer) clearInterval(timer);
        });

        // 提供给外部调用的方法 ---------------------------------------------------------------------------------------------------------

        // 外部-开始滚动 恢复正常滚动，解锁
        const outStartGroup = () => {
            state['isReady'] = true;
            startGroup();
        };

        // 外部-停止滚动 注：此方法执行后，会锁定滚动，移出事件不会重新开始滚动
        const outStopGroup = () => {
            state['isReady'] = false;
            stopGroup();
        };

        // 外部-跳转页
        const outGoCurrent = (index: number) => {
            goCurrent(index, 'bom');
        };

        //     return {
        //         ...toRefs(state),
        //         goCurrent,
        //         startGroup,
        //         stopGroup,
        //         changeCurrent,
        //         outStopGroup,
        //         outStartGroup,
        //         getSlotIndex,
        //         outGoCurrent
        //     };
        // }
        return () => {
            return (
                <div
                    class="carousel_main"
                    onMouseover={() => stopGroup()}
                    onMouseout={() => startGroup()}
                    style={{
                        '--width': width.value,
                        '--height': height.value,
                        '--timer': animationTime.value + 's',
                        '--animationType': animationType.value
                    }}>
                    <div class="slide_wraper">
                        <div
                            class={`slot_wraper ${
                                state.slot1Show
                                    ? `out_${
                                          groupType.value === 'transverse' ? state.direction : state.direction === 'left' ? 'top' : 'bottom'
                                      }`
                                    : ''
                            } ${
                                !state.isMoveSlot
                                    ? `in_${
                                           groupType.value === 'transverse' ? state.direction : state.direction === 'left' ? 'top' : 'bottom'
                                      }`
                                    : ''
                            } ${state.animationLock ? 'moveNone' : ''}`}>
                             {context.slots.default?.({ index: getSlotIndex('slot1') })}
                        </div>
                        <div
                            class={`slot_wraper ${
                                state.slot2Show
                                    ? `out_${
                                          groupType.value === 'transverse' ? state.direction : state.direction === 'left' ? 'top' : 'bottom'
                                      }`
                                    : ''
                            } ${
                                state.isMoveSlot
                                    ? `in_${
                                           groupType.value === 'transverse' ? state.direction : state.direction === 'left' ? 'top' : 'bottom'
                                      }`
                                    : ''
                            } ${state.animationLock ? 'moveNone' : ''}`}>                           
                            {context.slots.default?.({ index: getSlotIndex('slot2') })}
                        </div>
                        {props.showPaging && props.list.length > 1? <div class={`slide_pages ${groupType.value}`}>
                            {props.list.map((item, index) => (
                                <li class="slide_li_x" key={index} onClick={() => goCurrent(index, 'bom')}>
                                    <span class={`slide_point_x ${index === state.nowIndex ? 'active' : ''}`}></span>
                                </li>
                            ))}
                        </div>:''}
                       
                    </div>
                    {
                        props.showPrevNext && props.list.length > 1?  <div class="prev_btn" onClick={() => changeCurrent('prev')}></div> :''
                    }
                    
                   {
                        props.showPrevNext && props.list.length > 1?  <div class="next_btn" onClick={() => changeCurrent('next')}></div>:''
                    }
                </div>
            );
        };
    }
});
